#include <iostream>
#include <vector>

using namespace std;

namespace HQ
{
	template<class T>
	struct Myless
	{
		bool operator()(const T& x, const T& y)
		{
			return x < y;
		}
	};

	template<class T>
	struct Mygreater
	{
		bool operator()(const T& x, const T& y)
		{
			return x > y;
		}
	};

	template<class T, class Container = vector<T>, class Compare = Myless<T>>
	class priority_queue
	{
	public:
		priority_queue() = default;

		template<class InputIterator>
		priority_queue(InputIterator first, InputIterator last)
		{
			// 1.把数据全部存放到存储数据的容器中
			while (first != last) {
				_con.push_back(*first);
				++first;
			}
			// 2.向下调整建堆，默认为大堆
			for (int i = (_con.size() - 2) / 2; i >= 0; i--) {
				adjust_down(i);
			}
		}

		void adjust_up(int child)
		{
			Compare comfunc;
			int parent = (child - 1) / 2;
			while (child > 0) {
				//if (_con[parent] < _con[child]){
				//if (comfunc.operator()(_con[parent], _con[child])){
				if (comfunc(_con[parent], _con[child])) {
					swap(_con[parent], _con[child]);
					child = parent;
					parent = (child - 1) / 2;
				}
				else {
					break;
				}
			}
		}

		void adjust_down(int parent)
		{
			Compare comfunc;
			int child = parent * 2 + 1;
			while (child < _con.size()) {
				// 1.先选出左右孩子节点中较大的那个
				//if (child + 1 < _con.size() && _con[child] < _con[child + 1])
				if (child + 1 < _con.size() && comfunc(_con[child], _con[child + 1])) {
					child += 1;
				}
				// 2.将较大的那个节点跟父节点比较
				//if (_con[parent] < _con[child])
				if (comfunc(_con[parent], _con[child])) {
					swap(_con[child], _con[parent]);
					parent = child;
					child = parent * 2 + 1;
				}
				else {
					break;
				}
			}
		}

		void push(const T& x)
		{
			_con.push_back(x);
			adjust_up(_con.size() - 1);
		}

		void pop()
		{
			swap(_con[0], _con[_con.size() - 1]);
			_con.pop_back();
			adjust_down(0);
		}

		const T& top()
		{
			return _con[0];
		}

		size_t size()
		{
			return _con.size();
		}

		bool empty()
		{
			return _con.empty();
		}
	private:
		Container _con;
	};

}

int main()
{
	vector<int> v = { 1,5,3,6,5,4,1,8 };
	HQ::priority_queue<int> pq(v.begin(), v.end());

	while (!pq.empty()) {
		int top = pq.top();
		pq.pop();

		cout << top << " ";
	}
	cout << endl;

	return 0;
}

